package estates.facade;

import estates.addon.*;
import estates.model.Estate;
import estates.model.User;
import estates.model.Comment;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

public class Fasada1 {

  private List<Estate> katalogOfert = new ArrayList<Estate>();
  private List<User> katalogUsers = new ArrayList<User>();
  private List<Comment> komentarze = new ArrayList<Comment>();

  public Fasada1(List<Comment> c, List<Estate> e, List<User> u) {
    katalogOfert = e;
    katalogUsers = u;
    komentarze = c;
  }

  private ArrayList<Estate> wyszukaj_m_z_n(int m) {
    ArrayList<Estate> al = new ArrayList<Estate>();
    al.addAll(this.katalogOfert);

    if (al.size() > 185) {
      EstateRadixSort.EstateRadixSort(al);
    } else {
      Collections.sort((List) al);
    }

    int rozmiar = al.size();
    if (rozmiar > 3) {
      for (int i = 3; i < rozmiar; i++) {
        al.remove(al.get(3));
      }
    }
    return al;
  }

  public ArrayList<Estate> wyszukaj(HashMap<String, Object> wz) {
    FabrykaAbstrakcyjna f = new FabrykaStandard();
    Estate wzorzec = f.stworzOferte(wz);
    return wyszukaj(wzorzec);
  }

  public ArrayList<Estate> wyszukaj(Estate wzorzec) {
    ArrayList<Estate> wynik = new ArrayList<Estate>();
    for (Estate tmp : katalogOfert) {
      if (tmp.matchesQuery(wzorzec)) {
        wynik.add(tmp);
      }
    }
    return wynik;
  }

  public ArrayList<Estate> zestawOferty(HashMap<String, Object> wz) {
    FabrykaAbstrakcyjna f = new FabrykaStandard();
    Estate wzorzec = f.stworzOferte(wz);
    if (katalogOfert == null) {
      katalogOfert = wyszukaj(wzorzec);
    }
    return wyszukaj_m_z_n(wz.size() / 15);
  }

  public User Szukaj_user(String nip) {
    HashMap<String, Object> hm = new HashMap<String, Object>();
    hm.put("nip", nip);
    UsersFactory uf = new UsersFactory();
    User temp = uf.createUserTemplate(hm);
    int idx;
    if ((idx = katalogUsers.indexOf(temp)) != -1) {
      return katalogUsers.get(idx);
    }
    return null;
  }

  public User stworzUsera(HashMap<String, Object> hm) {
    UsersFactory uf = new UsersFactory();
    User user = uf.createUser(hm);
    if (Szukaj_user(user.getNIP()) == null) {
      katalogUsers.add(user);
      return user;
    }
    return null;
  }

  public Estate Szukaj_estate(String numer) {
    int nr = Integer.parseInt(numer);
    return Szukaj_estate(nr);
  }

  public Estate Szukaj_estate(Estate pom) {
    //HashMap<String, Object> hm = new HashMap<String, Object>();
    //hm.put("numer_oferty", (Integer) numer_oferty);
    //FabrykaStandard fabryka = new FabrykaStandard();
    //Estate temp = fabryka.stworzWzorzecOferty(hm);
    int idx;
    if ((idx = katalogOfert.indexOf(pom)) != -1) {
      return katalogOfert.get(idx);
    }
    return null;
  }
  

  public Estate Szukaj_estate(int numer_oferty) {
    HashMap<String, Object> hm = new HashMap<String, Object>();
    hm.put("numer_oferty", (Integer) numer_oferty);
    FabrykaStandard fabryka = new FabrykaStandard();
    Estate temp = fabryka.stworzWzorzecOferty(hm);
    return Szukaj_estate(temp);
  }

  public Estate Dodajoferte(HashMap<String, Object> hm1, HashMap<String, Object> hm2) {
    FabrykaStandard instance1 = new FabrykaStandard();
    hm1.put("numer_oferty", (Integer) katalogOfert.size());
    Estate estate = instance1.stworzOferte(hm1);
    UsersFactory instance2 = new UsersFactory();
    User user = instance2.createUser(hm2);
    User found;
    if ((found = Szukaj_user(user.getNIP())) != null) {
      estate.setUser(found);
      if (Szukaj_estate(estate) == null) {
        found.getEstates().add(estate);
        katalogOfert.add(estate);
        return estate;
      }
    }
    return null;
  }

  public List<Comment> getKomentarze() {
    return this.komentarze;
  }

  /**
   * @param comment - obiekt komentarza wyszukany w application beanie
   */
  public void acceptComment(Comment comment) {
    comment.setAccepted(true);
  }

  /**
   * @param comment - obiekt komentarza wyszukany w application beanie
   * @param cause - powod usuniecia komentarza
   */
  public void deleteComment(Comment comment, String cause) {
    comment.setCause(cause);
    comment.setDeleted(true);
  }

  public Comment Dodajkomentarz(HashMap<String, Object> commentData) {
    Estate estate = Szukaj_estate(Integer.parseInt((String) commentData.get("numer_oferty")));
    User user = Szukaj_user((String) commentData.get("nip"));

    String title = (String) commentData.get("title");
    String content = (String) commentData.get("content");

    // TODO: To mozna przeniesc do wzorca Budowniczy dla obiektu Comment
    Comment comment = new Comment();
    comment.setTitle(title);
    comment.setContent(content);
    comment.setUser(user);
    comment.setEstate(estate);

    if (comment != null) {
      komentarze.add(comment);
      return comment;
    }
    return null;
  }

  public List<Comment> getEstatesComments(String e) {
    return getEstatesComments(this.Szukaj_estate(e));
  }

  public List<Comment> getEstatesComments(Estate estate) {
    return estate.getComments();
  }

  public List<Comment> getUsersComments(User user) {
    return user.getComments();
  }

  public Comment getComment(Long commentId) {
    Iterator<Comment> iter = komentarze.iterator();
    Comment comment = null;
    while (iter.hasNext()) {
      comment = iter.next();
      if (comment.getId().equals(commentId)) {
        return comment;
      }
    }

    return null;
  }

  public List<Estate> getOferty() {
    return katalogOfert;
  }

  public List<User> getUzytkownicy() {
    return katalogUsers;
  }

  public ArrayList<Estate> getOfertyUzytkownika(String id_uz) {
    ArrayList<Estate> ar = new ArrayList();
    for (Estate e : katalogOfert) {
      if (e.getUser().getNIP().equals(id_uz)) {
        ar.add(e);
      }
    }

    return ar;
  }


  public boolean dodajDoObserwowanych(String nr_oferty, String nip_usera){
    Estate estate = Szukaj_estate(nr_oferty);

    User zglaszajacy = Szukaj_user(nip_usera);

    return zglaszajacy.dodajDoObserwowanych(estate);

  }

  public boolean usunZobserwowanych(String nr_oferty, String nip_usera){
    Estate estate = Szukaj_estate(nr_oferty);

    User zglaszajacy = Szukaj_user(nip_usera);
    
    return zglaszajacy.usunZObserwowanych(estate);
  }

  public boolean zglosZainteresowanie(String nipZglaszajacego, String nipWlasciciela, String nr_oferty, String smtp, String isp_smtp,
          String appMail) throws MessagingException{


    Estate estate = Szukaj_estate(Integer.parseInt(nr_oferty));
    User zglaszajacy = Szukaj_user(nipZglaszajacego);
    User wlasciciel = Szukaj_user(nipWlasciciela);
    String zglaszajacy_m = zglaszajacy.getMail();
    String wlasciciel_m =  wlasciciel.getMail();

    estate.setInterestedUser(zglaszajacy);

      boolean debug = false;

     Properties props = new Properties();
     props.put(smtp, isp_smtp);

    Session session = Session.getDefaultInstance(props, null);
    session.setDebug(debug);

    Message msg = new MimeMessage(session);

    InternetAddress addressFrom = new InternetAddress(appMail);
    msg.setFrom(addressFrom);

    InternetAddress[] addressTo = new InternetAddress[2];

    addressTo[0] = new InternetAddress(zglaszajacy_m);
    addressTo[1] = new InternetAddress(wlasciciel_m);

    msg.setRecipients(Message.RecipientType.TO, addressTo);


    msg.setSubject("Zgłoszenie zainteresowania nieruchomością.");
    String tekst = "Nasz serwis odnotował zgłoszenie zainteresowania użytkownika "+zglaszajacy.getLogin()+
            "nieruchomością o numerze ewidencyjnym " + estate.getId() + "wystawioną przez użytkownika " +
            wlasciciel.getLogin() + "\n";
    tekst+= "E-mail zainteresowanego: " + zglaszajacy_m + "\n";
    tekst+= "Telefon zainteresowanego: " + zglaszajacy.getPhone() + "\n";
    tekst+= "E-mail właściciela nieruchomości: " + wlasciciel_m + "\n";
    tekst+= "Telefon właściciela nieruchomości: " + wlasciciel.getPhone() + "\n";
    msg.setContent(tekst, "text/plain");
    Transport.send(msg);

    return true;
  }

  public boolean usunOferte(HashMap<String, Object> hm1, HashMap<String, Object> hm2) {
    FabrykaStandard instance1 = new FabrykaStandard();
    hm1.put("numer_oferty", (Integer) katalogOfert.size());
    Estate estate = instance1.stworzOferte(hm1);
    UsersFactory instance2 = new UsersFactory();
    User user = instance2.createUser(hm2);
    User found;

    if ((found = Szukaj_user(user.getNIP())) == null)return false;
      estate.setUser(found);
     // if (Szukaj_estate(estate) != null) {
    return  katalogOfert.remove(estate);

       /* return true;
      }
    }
    return false;*/
  }

  public boolean edytujOferte(HashMap<String, Object> hm1, HashMap<String, Object> hm2, HashMap<String, Object> nowa) {
    FabrykaStandard instance1 = new FabrykaStandard();
    hm1.put("numer_oferty", (Integer) katalogOfert.size());
    Estate estate = instance1.stworzOferte(hm1);
   // Estate nowy = instance1.stworzOferte(nowa);
  //  UsersFactory instance2 = new UsersFactory();
  //  User user = instance2.createUser(hm2);
   // User found;
  //  if ((found = Szukaj_user(user.getNIP())) != null) {
      //estate.setUser(found);
    //  nowy.setUser(found);
    Estate znal=Szukaj_estate(estate);
      if (znal!= null ) {
          znal.update(nowa);
       return true;
      }
   
    return false;
  }
}
